/**
 * Created by xiey on 2016/3/16.
 *
 * 储存 field 配置
 *
 See valid URLs in RFC3987 (http://tools.ietf.org/html/rfc3987)
 var URL_REGEXP = /^[a-z][a-z\d.+-]*:\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\s:/?#]+|\[[a-f\d:]+\])(?::\d+)?(?:\/[^?#]*)?(?:\?[^#]*)?(?:#.*)?$/i;
 var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;
 var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/;
 var DATE_REGEXP = /^(\d{4,})-(\d{2})-(\d{2})$/;
 var DATETIMELOCAL_REGEXP = /^(\d{4,})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;
 var WEEK_REGEXP = /^(\d{4,})-W(\d\d)$/;
 var MONTH_REGEXP = /^(\d{4,})-(\d\d)$/;
 var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/;

 */
as.value('$$FIELD_DEFAULT_MSG', {
    defaultMsg : '验证未通过',
    minlength  : '至少输入{{minlength}}位',
    maxlength  : '最多输入{{maxlength}}位',
    required   : '请输入{{label}}',
    selRequired: '请选择{{label}}'
}).value('$$FIELD_VTYPE', {
    email: {
        pattern: /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,
        msg    : '请输入正确的邮箱地址'
    },
    // See valid URLs in RFC3987 (http://tools.ietf.org/html/rfc3987)
    url  : {
        pattern: /^[a-z][a-z\d.+-]*:\/*(?:[^:@]+(?::[^@]+)?@)?(?:[^\s:/?#]+|\[[a-f\d:]+\])(?::\d+)?(?:\/[^?#]*)?(?:\?[^#]*)?(?:#.*)?$/i,
        msg    : '请输入正确的URL地址'
    }
}).directive('aField', ['$$FIELD_VTYPE', function ($$FIELD_VTYPE) {
    return {
        require   : {
            model: 'ngModel',
            field: 'aField'
        },
        restrict  : 'EA',
        scope     : {
            field: '='
        },
        replace   : true,
        template  : function () {
            var content = [];
            content.push('<div class="form-group">');
            content.push('  <field-label class="col-md-3 control-label alignment"></field-label>');
            content.push('  <div ng-switch="field.type" class="controls col-md-8" a-tooltip="{{errorMsg}}">');
            content.push('    <file-field ng-switch-when="file"></file-field>');
            content.push('    <date-field ng-switch-when="date" field-config="field"></date-field>');
            content.push('    <date-field ng-switch-when="month" field-config="field"></date-field>');
            content.push('    <date-field ng-switch-when="year" field-config="field"></date-field>');
            content.push('    <combobox-field ng-switch-when="combobox"></combobox-field>');
            content.push('    <checkbox-field ng-switch-when="checkbox"></checkbox-field>');
            content.push('    <radio-field ng-switch-when="radio"></radio-field>');
            content.push('    <number-field ng-switch-when="number"></number-field>');
            content.push('    <text-field ng-switch-default></text-field>');
            content.push('  </div>');
            content.push('  <label ng-if="showError" class="control-label">');
            content.push('    <i class="glyphicon glyphicon-exclamation-sign"></i>');
            content.push('  </label>');
            content.push('</div>');
            return content.join('');
        },
        link      : function (scope, el, attr, req) {
            var ngModel = req.model, field = req.field, fieldCfg = field.getFieldCfg(), vtype = $$FIELD_VTYPE[fieldCfg.vtype];
            scope.model = req.model;
            var getPriority = function (keys) {
                // todo 如果有多个同时出现的 key, 根据配置的优先级返回
                return keys[0];
            };
            if (fieldCfg.message.required) {
                // 添加 required 默认验证方式
                ngModel.$validators.required = function (modelValue, viewValue) {
                    var value = modelValue || viewValue;
                    return value !== undefined && value !== null && value.length !== 0;
                };
            }
            if (fieldCfg.message.pattern) {
                // 添加 pattern 默认验证方式
                ngModel.$validators.pattern = function (modelValue, viewValue) {
                    var value = modelValue || viewValue;
                    if (value === undefined || value === '') {
                        return true;
                    }
                    return fieldCfg.message.pattern.value.test(value);
                };
            }
            if (vtype) {
                // 添加 pattern 默认验证方式
                ngModel.$validators.vtype = function (modelValue, viewValue) {
                    var value = modelValue || viewValue;
                    if (value === undefined || value === '') {
                        return true;
                    }
                    return vtype.pattern.test(value);
                };
            }
            scope.$watch('model.$viewValue', function () {
                if (req.model.$dirty) {
                    req.model.$invalid ? (el.addClass('has-error')) : (el.removeClass('has-error'));
                    scope.showError = req.model.$invalid;
                }
                scope.field.hasError = req.model.$invalid;
            });
            scope.$watchCollection('model.$error', function (nv) {
                if (nv) {
                    var m = fieldCfg.message[getPriority(Object.keys(nv))];
                    if (m) {
                        req.model.$dirty && field.setError(m.msg);
                    } else {
                        field.setError('');
                    }
                }
            });

            ////////////////////////////////////////////////////
            scope.field.checkError = function () {
                var m = fieldCfg.message[getPriority(Object.keys(ngModel.$error))];
                req.model.$dirty = true;
                req.model.$invalid && field.setError(m.msg);
            };
            scope.field.setError = field.setError;
        },
        controller: ['$scope', '$interpolate', '$element', '$$FIELD_DEFAULT_MSG', function ($scope, $interpolate, $element, $$FIELD_DEFAULT_MSG) {
            var ctrl = this, transforms = ['minlength', 'maxlength'], field = $scope.field;
            field.message = field.message || {};
            // 添加 allowBlank 快捷方式
            if (field.allowBlank === false) {
                field.message.required = field.message.required || true;
            }
            angular.forEach(field.message, function (value, key) {
                // 配置的是简写形式时进行转换
                if (toString.call(value) !== '[object Object]') {
                    var val = value;
                    var msg = $$FIELD_DEFAULT_MSG.defaultMsg;
                    if (key === 'required') {
                        val = (val !== false);
                        if (['radio', 'checkbox', 'combobox', 'file', 'date', 'month', 'year'].indexOf(field.type) !== -1) {
                            msg = (value.length ? value : $interpolate($$FIELD_DEFAULT_MSG['selRequired'])(field));
                        }else{
                            msg = (value.length ? value : $interpolate($$FIELD_DEFAULT_MSG[key])(field));
                        }
                    }
                    if (transforms.indexOf(key) !== -1) {
                        msg = $interpolate($$FIELD_DEFAULT_MSG[key])(field.message);
                    }
                    field.message[key] = {
                        value: val,
                        msg  : msg
                    };
                }
            });
            var vtype = $$FIELD_VTYPE[field.vtype];
            if (vtype) {
                field.message.vtype = {
                    value: vtype.pattern,
                    msg  : vtype.msg
                };
            }

            ////////////////////////////////////////////////////
            ctrl.getFieldCfg = function () {
                return angular.copy(field);
            };
            ctrl.setError = function (msg) {
                $scope.errorMsg = msg;
                $scope.showError = !!msg;
                !!msg ? $element.addClass('has-error') : $element.removeClass('has-error');
            };
        }]
    };
}]);